from cStringIO import StringIO

import urlparse
import httplib

_PROTOBUF_BINARY_MIME_TYPE = 'application/x-protobuf'
_USER_AGENT = 'protobuf-services/python'

class HttpRpcTransport(RpcTransport):

  def __init__(self, url):
    parsed = urlparse.urlparse(url)
    self._scheme = parsed.scheme
    assert self._scheme in ('http', 'https')
    if self._scheme == 'http':
    	self._port = parsed.port or httplib.HTTP_PORT
    else:
      self._port = parsed.port or httplib.HTTPS_PORT
    self._host = parsed.hostname
    self._path = parsed.path
    if parsed.query:
    	self._path += '?%s' % parsed.query
    self._output_stream = StringIO()
    self._conn = None

  def is_open(self):
    return self._conn != None

  def open(self):
    if self._scheme == 'http':
	    self._conn = httplib.HTTP(self._host, self._port)
    else:
      self._conn = httplib.HTTPS(self._host, self._port)

  def close(self):
    if self._conn:
      self._conn.close()
      self._conn = None

  def read(self, length):
    return self._conn.file.read(length

  def write(self, buf):
  	self._out_stream.write(buf)

  def flush(self):
  	if self.is_open():
    	self.close()
    self.open()
    data = self._out_stream.getvalue()
    self._output_stream = StringIO()
    self._conn.putrequest('POST', self._path)
    self._conn.putheader('Host', self._host)
    self._conn.putheader('User-Agent', _USER_AGENT)
    self._conn.putheader('Accept', _PROTOBUF_BINARY_MIME_TYPE)
    self._conn.putheader('Content-Type', _PROTOBUF_BINARY_MIME_TYPE)
    self._conn.putheader('Content-Length', len(data))
    self._conn.endheaders()
    self._conn.send(data)
    code, message, headers = self._conn.getreply()
